<?php
/**
 * Created by PhpStorm.
 * User: 764432054@qq.com
 * Date: 2020/7/12
 * Time: 23:52
 */

class client
{
    public $context;
    public $sock;
    public $protocol = 'tcp';
    public $host = '0.0.0.0';
    public $port = 9501;
    /** @var float */
    protected $connection_timeout=3;

    /** @var string */
    private static $ERRNO_EQUALS_EAGAIN;

    /** @var string */
    private static $ERRNO_EQUALS_EWOULDBLOCK;

    /** @var string */
    private static $ERRNO_EQUALS_EINTR;

    public $last_error = [];

    public function __construct()
    {
        $this->context = stream_context_create(
            [
                "socket" =>
                    ["tcp_nodelay" => true]
            ]
        );
        $remote = sprintf(
            '%s://%s:%s',
            $this->protocol,
            $this->host,
            $this->port
        );

        $this->set_error_handler();

        $this->sock = stream_socket_client(
            $remote,
            $errno,
            $errstr,
            $this->connection_timeout,
            STREAM_CLIENT_CONNECT,
            $this->context
        );

        $this->cleanup_error_handler();

    }
    public function getSock(){
        return $this->sock;
    }

    protected function set_error_handler()
    {
        $this->last_error = null;
        set_error_handler(array($this, 'error_handler'));
    }

    public function error_handler($errno, $errstr, $errfile, $errline, $errcontext = null)
    {
        // fwrite notice that the stream isn't ready - EAGAIN or EWOULDBLOCK
        if (strpos($errstr, self::$ERRNO_EQUALS_EAGAIN) !== false || strpos($errstr, self::$ERRNO_EQUALS_EWOULDBLOCK) !== false) {
            // it's allowed to retry
            return null;
        }

        // stream_select warning that it has been interrupted by a signal - EINTR
        if (strpos($errstr, self::$ERRNO_EQUALS_EINTR) !== false) {
            // it's allowed while processing signals
            return null;
        }

        // throwing an exception in an error handler will halt execution
        //   set the last error and continue
        $this->last_error = compact('errno', 'errstr', 'errfile', 'errline', 'errcontext');
    }

    /**
     * throws an ErrorException if an error was handled
     */
    protected function cleanup_error_handler()
    {
        if ($this->last_error !== null) {
            throw new \ErrorException($this->last_error['errstr'], 0, $this->last_error['errno'], $this->last_error['errfile'], $this->last_error['errline']);
        }

        // no error was caught
        restore_error_handler();
    }
}
$client=new client();
$sock=$client->getSock();
$str='client-'.date("Y-m-d H:i:s").PHP_EOL;
fwrite($sock,$str,strlen($str));
echo fread($sock, 1024);
fclose($sock);





